import {Behaviour, getGameObjectById, SpriteRenderer, Transform} from "../gameengine";
import {MainRoleBehaviour} from "../mainRoleBehaviour";
import {
    SceneFollowState,
    sceneMoveMachine,
} from "./sceneMoveMachine";
import {AnimationRenderer} from "../AnimationRenderer";
import { TileMapRenderer } from "../tilemap";

export class SceneFollow extends Behaviour {

    private sceneTransform:Transform;
    private characterTransform:Transform;

    private centerPosX:number;
    private centerPosY:number;

    private characterPosXtoCanvas:number;
    private characterPosYtoCanvas:number;

    private speedX;
    private speedY;

    public atCenterX:boolean;
    public atCenterY:boolean;

    public atLeft:boolean;
    public atRight:boolean;
    public atTop:boolean;
    public atBottom:boolean;

    public sceneWidth=800;
    public sceneHeight=450;

    private mapWidth:number;
    private mapHeight:number;

    private mainRoleBehaviour:MainRoleBehaviour;

    protected onStart() {
        this.sceneTransform=getGameObjectById("Scene").getScript(Transform);
        this.characterTransform=getGameObjectById("mainRole").getScript(Transform);

        this.getMapSize();
        this.getMainRoleBehavoiur();
        this.getCenterPos();
    }

    protected onUpdate(advancedTime: number) {
        this.getSpeed();
        this.getRelativePos();
        this.checkIsAtCenterPoint();
        this.checkEdge();

        const speeds=this.directionLock();
        sceneMoveMachine.changeState(new SceneFollowState(-speeds.speedX,-speeds.speedY));

    }


    private getMainRoleBehavoiur(){
        const character=getGameObjectById("mainRole");
        this.mainRoleBehaviour=character.getScript(MainRoleBehaviour);
    }

    private getMapSize(){
        const scene=getGameObjectById("tilemap");
        const tilemapRenderer=scene.getScript(TileMapRenderer);

        this.mapWidth=tilemapRenderer.getRenderArea().width;
        console.log(this.mapWidth);
        this.mapHeight=tilemapRenderer.getRenderArea().height;
        console.log(this.mapHeight);
    }

    private getCenterPos(){
        const character=getGameObjectById("mainRole");
        const animRender=character.getScript(AnimationRenderer);

        const characterWidth=animRender.getRenderArea().width;
        const characterHeight=animRender.getRenderArea().height;

        const canvasCenterX=this.sceneWidth/2;
        const canvasCenterY=this.sceneHeight/2;

        this.centerPosX=canvasCenterX-characterWidth/2;
        this.centerPosY=canvasCenterY-characterHeight/2;
    }

    private getRelativePos(){

        const startX=-this.sceneTransform.x;
        const startY=-this.sceneTransform.y;

        this.characterPosXtoCanvas=this.characterTransform.x-startX;
        this.characterPosYtoCanvas=this.characterTransform.y-startY;
    }

    private getSpeed(){
        const speeds=this.mainRoleBehaviour.getSpeed();
        this.speedX=speeds.x;
        this.speedY=speeds.y;
    }

    public checkIsAtCenterPoint(){
        this.atCenterX=false;
        this.atCenterY=false;

        if(Math.abs(this.characterPosXtoCanvas-this.centerPosX)<=2){
            this.atCenterX=true;
        }

        if(Math.abs(this.characterPosYtoCanvas-this.centerPosY)<=2){
            this.atCenterY=true;
        }
    }

    public checkEdge(){
        const distanceToLeft=Math.abs(this.sceneTransform.x);
        const distanceToRight=Math.abs(this.sceneTransform.x+this.mapWidth-this.sceneWidth);
        const distanceToTop=Math.abs(this.sceneTransform.y);
        const distanceToBottom=Math.abs(this.sceneTransform.y+this.mapHeight-this.sceneHeight);

        this.atLeft=false;
        this.atRight=false;
        this.atTop=false;
        this.atBottom=false;

        if(distanceToLeft<=2||this.sceneTransform.x>0){
            this.atLeft=true;
        }else if(distanceToRight<=2||this.sceneTransform.x+this.mapWidth-this.sceneWidth<0){
            this.atRight=true;
        }

        if(distanceToTop<=2||this.sceneTransform.y>0){
            this.atTop=true;
        }else if(distanceToBottom<=2||this.sceneTransform.y+this.mapHeight-this.sceneHeight<0){
            this.atBottom=true;
        }
    }

    public directionLock() {
        var speedX = this.speedX;
        var speedY = this.speedY;

        if (!this.atCenterX) {
            speedX = 0;
        }
        if (!this.atCenterY) {
            speedY = 0;
        }

        if (this.atLeft)
            speedX = speedX < 0 ? 0 : speedX;

        if (this.atRight)
            speedX = speedX > 0 ? 0 : speedX;

        if (this.atTop)
            speedY = speedY < 0 ? 0 : speedY;

        if (this.atBottom)
            speedY = speedY > 0 ? 0 : speedY;

        if(this.mapWidth<=this.sceneWidth){
            speedX=0;
        }

        if(this.mapHeight<=this.sceneHeight){
            speedY=0;
        }


        return {speedX: speedX, speedY: speedY};
    }
}